/**
 * 速算选择题生成器
 */
import QuestionGeneratorBase from './question-generator-base.js';
import SpeedCalcGenerator from './question-generator-speed-calc.js';

class SpeedCalcChoiceGenerator extends QuestionGeneratorBase {
    /**
     * 生成速算选择题
     * @param {Object} options 选项配置
     * @returns {Array} 题目数组
     */
    static generateQuestions(options = {}) {
        const {
            count = 10,
            operations = ['add', 'subtract', 'multiply', 'divide'],
            valueTypes = ['integer', 'decimal'],
            digitRange = {min: 2, max: 5},
            optionsCount = 4
        } = options;

        const questions = [];

        for (let i = 0; i < count; i++) {
            const operation = operations[Math.floor(Math.random() * operations.length)];
            const valueType = valueTypes[Math.floor(Math.random() * valueTypes.length)];

            // 生成基础题目
            const baseQuestion = SpeedCalcGenerator.generateSingleCalcQuestion(operation, valueType, digitRange);
            const correctAnswer = baseQuestion.answer;

            // 判断是否应该生成整数选项
            // 对于加法、减法、乘法，如果两个操作数都是整数，则选项也应该是整数
            const shouldBeInteger = (operation === 'add' || operation === 'subtract' || operation === 'multiply') && 
                                    Number.isInteger(baseQuestion.operand1) && 
                                    Number.isInteger(baseQuestion.operand2);

            // 判断是否只有1个操作数具有小数部分（增加难度）
            // 对于加法、减法、乘法，如果只有1个操作数有小数部分，则干扰项保留正确答案的小数部分
            const operand1HasDecimal = !Number.isInteger(baseQuestion.operand1);
            const operand2HasDecimal = !Number.isInteger(baseQuestion.operand2);
            const shouldPreserveDecimalPart = (operation === 'add' || operation === 'subtract' || operation === 'multiply') && 
                                              (operand1HasDecimal !== operand2HasDecimal); // XOR: 只有一个为true
            
            // 提取正确答案的小数部分（如果需要保留）
            const correctAnswerDecimalPart = shouldPreserveDecimalPart ? correctAnswer - Math.floor(correctAnswer) : 0;

            // 生成选项（包含正确答案和干扰项）
            const optionsSet = new Set([this.formatAnswerForChoice(correctAnswer, valueType)]);

            // 生成干扰项
            let distractorAttempts = 0;
            const maxDistractorAttempts = 50; // 防止无限循环

            while (optionsSet.size < optionsCount && distractorAttempts < maxDistractorAttempts) {
                distractorAttempts++;

                // 使用不同策略生成干扰项
                let distractor;
                const strategy = Math.random();

                if (strategy < 0.3) {
                    // 策略1: 常见计算错误（如符号错误、进位错误等）
                    distractor = this.generateCommonMistake(baseQuestion, operation, valueType);
                } else if (strategy < 0.6) {
                    // 策略2: 答案附近的值
                    const offset = (Math.random() - 0.5) * Math.abs(correctAnswer) * 0.3;
                    distractor = correctAnswer + offset;
                } else {
                    // 策略3: 随机但合理的值
                    const range = Math.min(Math.abs(correctAnswer) || 1000, 10000);
                    distractor = correctAnswer + (Math.random() - 0.5) * range;
                }

                // 如果需要保留小数部分，则替换为正确答案的小数部分
                if (shouldPreserveDecimalPart) {
                    const distractorIntegerPart = Math.floor(distractor);
                    distractor = distractorIntegerPart + correctAnswerDecimalPart;
                    distractor = this.roundToDecimalPlaces(distractor, 2);
                } else if (shouldBeInteger) {
                    // 如果应该是整数，则向下取整
                    distractor = Math.round(distractor);
                } else {
                    distractor = this.roundToDecimalPlaces(distractor, 2);
                }

                // 确保干扰项的整数部分不超过5位
                let integerPart = Math.floor(Math.abs(distractor));
                if (integerPart >= 100000) {
                    // 按比例缩小到5位以内
                    const scale = Math.ceil(integerPart / 99999);
                    distractor = this.roundToDecimalPlaces(distractor / scale, 2);
                    if (shouldBeInteger) {
                        distractor = Math.round(distractor);
                    }
                }

                // 确保干扰项为正数且合理
                if (distractor < 0) {
                    distractor = Math.abs(distractor);
                }

                const formattedDistractor = this.formatAnswerForChoice(distractor, valueType);

                // 确保干扰项不重复且与正确答案不同
                const correctAnswerFormatted = this.formatAnswerForChoice(correctAnswer, valueType);
                if (!optionsSet.has(formattedDistractor) && formattedDistractor !== correctAnswerFormatted) {
                    optionsSet.add(formattedDistractor);
                }
            }

            // 打乱选项顺序
            const optionsArray = Array.from(optionsSet);
            const shuffledOptions = this.shuffleArray(optionsArray);
            const correctIndex = shuffledOptions.indexOf(this.formatAnswerForChoice(correctAnswer, valueType));

            questions.push({
                id: `calc_choice_${Date.now()}_${i}`,
                question: baseQuestion.question,
                correctAnswer: this.formatAnswerForChoice(correctAnswer, valueType),
                options: shuffledOptions,
                correctIndex: correctIndex,
                operation: operation,
                valueType: valueType,
                userAnswer: null,
                isCorrect: null,
                timeUsed: 0
            });
        }

        return questions;
    }

    /**
     * 生成常见计算错误（干扰项）
     */
    static generateCommonMistake(question, operation, valueType) {
        const {operand1, operand2, answer} = question;
        let mistake;

        const mistakeType = Math.random();

        if (mistakeType < 0.25 && operation === 'subtract') {
            // 减法符号错误 -> 变成加法
            mistake = operand1 + operand2;
        } else if (mistakeType < 0.5 && operation === 'add') {
            // 加法符号错误 -> 变成减法
            mistake = Math.abs(operand1 - operand2);
        } else if (mistakeType < 0.75 && operation === 'multiply') {
            // 乘法错误 -> 使用加法
            mistake = operand1 + operand2;
        } else {
            // 数量级错误（仅在不会导致超过5位数时使用）
            const scaledUp = answer * 10;
            const scaledDown = answer * 0.1;

            // 选择不会超过5位数的缩放
            if (Math.floor(Math.abs(scaledUp)) < 100000) {
                mistake = scaledUp;
            } else if (Math.floor(Math.abs(scaledDown)) >= 1) {
                mistake = scaledDown;
            } else {
                // 如果都不合适，使用答案附近的偏移
                mistake = answer + (Math.random() - 0.5) * Math.abs(answer) * 0.5;
            }
        }

        // 确保错误答案的整数部分不超过5位
        let integerPart = Math.floor(Math.abs(mistake));
        if (integerPart >= 100000) {
            const scale = Math.ceil(integerPart / 99999);
            mistake = mistake / scale;
        }

        // 确保结果为正数
        mistake = Math.abs(mistake);

        return this.roundToDecimalPlaces(mistake, 2);
    }
}

export default SpeedCalcChoiceGenerator;

